package login

import (
	"context"
	"time"

	"server_1.0/api/internal/svc"
	"server_1.0/api/internal/types"
	"server_1.0/service/student/student"
	"server_1.0/util"

	"github.com/golang-jwt/jwt"
	"github.com/zeromicro/go-zero/core/logx"
)

type StudentLoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewStudentLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StudentLoginLogic {
	return &StudentLoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *StudentLoginLogic) StudentLogin(req *types.StuLoginRep) (resp *types.PostReps, err error) {
	Reps, err := l.svcCtx.StudentRpc.QueryID(l.ctx, &student.QueryIDReq{
		No: req.Username,
	})
	code := util.Success
	Msg := "成功"
	if err != nil {
		code = util.NoFoundError
		Msg = "无记录"
	} else {
		sig := Reps.QRs[0]
		if req.Password != sig.Password {
			code = util.NoFoundError
			Msg = "密码错误"
		} else {
			now := time.Now().Unix()
			accessExpire := l.svcCtx.Config.JwtAuth.AccessExpire
			jwtToken, err := l.getJwtToken(l.svcCtx.Config.JwtAuth.AccessSecret, now, accessExpire, sig.No)
			if err != nil {
				return nil, util.NewCodeError(util.Error, "失败")
			}
			l.svcCtx.Redis.Set("loginUserId:"+sig.No, sig.Name+";"+sig.Sex+";", time.Duration(accessExpire)*time.Second)
			l.svcCtx.Redis.Do("SADD", "loginStatus", sig.No)
			return &types.PostReps{
				Code: code,
				Msg:  Msg,
				Data: map[string]interface{}{
					"No":          sig.No,
					"Name":        sig.Name,
					"Sex":         sig.Sex,
					"Age":         sig.Age,
					"Token":       jwtToken,
					"ExprieTime":  now + accessExpire,
					"RefreshTime": now + accessExpire/2,
				},
			}, nil
		}
		return &types.PostReps{
			Code: code,
			Msg:  Msg,
		}, nil
	}
	return &types.PostReps{
		Code: code,
		Msg:  Msg,
	}, nil
}

func (l *StudentLoginLogic) getJwtToken(secretKey string, iat, seconds int64, userId string) (string, error) {
	claims := make(jwt.MapClaims)
	claims["exp"] = iat + seconds
	claims["iat"] = iat
	claims["userId"] = userId
	token := jwt.New(jwt.SigningMethodHS256)
	token.Claims = claims
	return token.SignedString([]byte(secretKey))
}
